Olaf adds Navigon Mobile Navigator 4.
authorrobertl <robertl@f51c46e8-681c-474f-0cfe-069cfd0219fb>
Tue, 13 Sep 2005 23:24:47 +0000 (23:24 +0000)
committerrobertl <robertl@f51c46e8-681c-474f-0cfe-069cfd0219fb>
Tue, 13 Sep 2005 23:24:47 +0000 (23:24 +0000)
gpsbabel/Makefile
gpsbabel/README
gpsbabel/nmn4.c [new file with mode: 0644]
gpsbabel/reference/route/nmn4-sample-out.rte [new file with mode: 0644]
gpsbabel/reference/route/nmn4-sample.gpx [new file with mode: 0644]
gpsbabel/reference/route/nmn4-sample.rte [new file with mode: 0644]
gpsbabel/testo
gpsbabel/vecs.c

index f89ac1f567c014d279d9330dfa059c87904a6c53..35ccd4f58c9ceb82099ed2277c9c4ee058451ce4 100644 (file)
@@ -39,7 +39,7 @@ FMTS=magproto.o gpx.o geo.o mapsend.o mapsource.o garmin_tables.o \
        igc.o brauniger_iq.o shape.o hiketech.o glogbook.o coastexp.o \
        vcf.o overlay.o kml.o google.o lowranceusr.o an1.o tomtom.o \
        tef_xml.o maggeo.o pathaway.o vitosmt.o gdb.o bcr.o coto.o \
-       ignrando.o stmwpp.o msroute.o cst.o nmn5.o
+       ignrando.o stmwpp.o msroute.o cst.o nmn4.o nmn5.o
 
 FILTERS=position.o duplicate.o arcdist.o polygon.o smplrout.o reverse_route.o sort.o stackfilter.o trackfilter.o discard.o
 
@@ -220,6 +220,7 @@ msroute.o: msroute.c defs.h queue.h gbtypes.h
 navicache.o: navicache.c defs.h queue.h gbtypes.h cet_util.h
 netstumbler.o: netstumbler.c defs.h queue.h gbtypes.h csv_util.h
 nmea.o: nmea.c defs.h queue.h gbtypes.h
+nmn4.o: nmn4.c defs.h queue.h gbtypes.h
 nmn5.o: nmn5.c defs.h queue.h gbtypes.h coldsync/palm.h coldsync/pdb.h \
   jeeps/gpsmath.h
 overlay.o: overlay.c defs.h queue.h gbtypes.h grtcirc.h
index 14d782a5a10d37e5f0b546247cadbe7ac8add832..6334b82b8a8199109309252ca00893f08e2ffd60 100644 (file)
@@ -1076,22 +1076,32 @@ THE FORMATS
        will not be supported.
 
     CST
-    
-       With this format we can read CarteSurTable data files.
-       CarteSurTable is a shareware program widely used in France.
-       The data inside have to be seen as a mixture of a waypoints list,
-       one route and several tracks.
-       
-       http://phgiraud.free.fr/CarteSurTable/CarteSurTable.htm
-       
+
+        With this format we can read CarteSurTable data files.
+        CarteSurTable is a shareware program widely used in France.  The
+        data inside have to be seen as a mixture of a waypoints list,
+        one route and several tracks.
+
+        http://phgiraud.free.fr/CarteSurTable/CarteSurTable.htm
+
+    nmn4
+
+        Support for Navigon Mobile Navigator route (.rte) files.  This
+        is a very simple text format that only requires coordinates, but
+        has fields for many other things.  We only write coordinates as
+        fields like 'city' and 'street' cannot typically be populated
+        from other formats.
+
+        http://www.navigon.com
+
     nmn5
-    
-       Support for Navigon Mobile Navigator 5 Palm/OS files.
-       This is a route-only format. 
-       
-       http://www.navigon.com
-       
-       
+
+        Support for Navigon Mobile Navigator 5 Palm/OS files.  This is a
+        route-only format.
+
+        http://www.navigon.com
+
+
 DATA FILTERS
 
         GPSBabel supports data filtering.  Data filters are invoked from
diff --git a/gpsbabel/nmn4.c b/gpsbabel/nmn4.c
new file mode 100644 (file)
index 0000000..1be8910
--- /dev/null
@@ -0,0 +1,355 @@
+ /*
+
+    Support for Navigon Mobile Navigator .rte files.
+
+    Copyright (C) 2005 Olaf Klein, o.b.klein@t-online.de
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA
+*/
+
+/*
+    line structure, items delimited by '|'
+
+-|-|17|-|ZIP-Code|City|ZIP-Code2|Street|No.|-|-|longitude|latitude|-|-| + 0D0A
+
+*/
+
+#include "defs.h"
+#include "csv_util.h"
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+
+static FILE *fin;
+static FILE *fout;
+static char *fin_name, *fout_name;
+static int curr_rte_num, target_rte_num;
+static int iter;
+
+#define MYNAME "navigon"
+
+static char *index_opt;
+
+static
+arglist_t nmn4_args[] = {
+       {"index", &index_opt, "Index of route to write (if more the one in source)", NULL, ARGTYPE_INT },
+       {0, 0, 0, 0, 0}
+};
+
+
+/* helpers */
+
+void
+nmn4_fwrite(FILE *fout, const char *fmt, ...)
+{
+
+       va_list args;
+       int res;
+       
+       va_start(args, fmt);
+       res = vfprintf(fout, fmt, args);
+       is_fatal((res < 0),
+               MYNAME ": error (%d) while writing to \"%s\"!\n", 0-res, fout_name);
+       va_end(args);
+}
+
+static char *
+nmn4_concat(char *arg0, ...)
+{
+       va_list args;
+       char *src, *res;
+       
+       res = NULL;
+       va_start(args, arg0);
+       src = (char *)arg0;
+
+       while (src != NULL)
+       {
+               char *c = lrtrim(src);
+               
+               if (*c != '\0')
+               {
+                       if (res == NULL)
+                               res = xstrdup(c);
+                       else
+                       {
+                               res = xstrappend(res, " ");
+                               res = xstrappend(res, c);
+                       }
+               }
+               xfree(src);
+               src = va_arg(args, char *);
+       }
+       va_end(args);
+       
+       return res;
+}
+
+static char *
+nmn4_read_line(char *buff, size_t buffsize, FILE *fin)
+{
+       char *res, *c;
+       
+       while ((res = fgets(buff, buffsize, fin)))
+       {
+               res = lrtrim(res);
+               if (*res == '\0') continue;
+               return res;
+       }
+       return NULL;
+}
+
+static void
+nmn4_check_line(char *line)
+{
+       char *c = line;
+       int i = 0;
+       while ((c = strchr(c, '|')))
+       {
+               c++;
+               i++;
+       }
+       is_fatal((i != 15),
+               MYNAME ": Invalid or unknown structure!");
+}
+
+static void
+nmn4_read_data(void)
+{
+       char buff[1024];
+       char *str, *c;
+       int column;
+
+       char *zip1, *zip2, *city, *street, *number;     
+       route_head *route;
+       waypoint *wpt;
+       
+       route = route_head_alloc();
+       route_add_head(route);
+       
+       while ((str = nmn4_read_line(buff, sizeof(buff), fin)))
+       {
+               nmn4_check_line(buff);
+
+               /* for a quiet compiler */
+               zip1 = zip2 = city = street = number = NULL;
+           
+               wpt = waypt_new();
+           
+               column = -1;
+               c = csv_lineparse(str, "|", "", column++);
+               while (c != NULL)
+               {
+                       switch(column)
+                       {
+                               case  0: /* "-" */      /* unknown fields for the moment */
+                               case  1: /* "-" */
+                               case  2: /* "-" */
+                               case  3: /* "-" */
+                               case  9: /* "-" */
+                               case 10: /* "-" */
+                               case 13: /* "-" */
+                               case 14: /* "-" */
+                               case 15: /* "" */
+                                       break;
+                   
+                               case  4:                                /* ZIP Code */
+                                       if (*c != '-') 
+                                               zip1 = xstrdup(c);
+                                       else
+                                               zip1 = xstrdup("");
+                                       break;
+                       
+                               case  5:                                /* City */
+                                       if (*c != '-')
+                                               city = xstrdup(c); 
+                                       else
+                                               city = xstrdup("");
+                                       break;
+                       
+                               case  6:                                /* ZIP Code -2- */
+                                       if (*c != '-') 
+                                               zip2 = xstrdup(c); 
+                                       else
+                                               zip2 = xstrdup("");     
+                                       break;
+                                       
+                               case  7:                                /* Street */
+                                       if (*c != '-')
+                                               street = xstrdup(c); 
+                                       else
+                                               street = xstrdup("");
+                                       break;
+                                       
+                               case  8:                                /* Number */
+                                       if (*c != '-')
+                                               number = xstrdup(c); 
+                                       else
+                                               number = xstrdup("");
+
+                               /* 
+                                  This is our final index
+                                  All stuff for generating names or comments
+                                  is hold locally.
+                                  
+                                  We don't have fields for street, city or zip-code.
+                                  Instead we construct a description from that.
+                               */
+                       
+                                       if (strcmp(zip1, zip2) == 0) *zip2 = '\0';
+                                       if (*city != '\0')
+                                       {
+                                               /* 
+                                                  if any field following city has a value, add a comma to city 
+                                               */
+                                               if ((*street != '\0') || (*number != '\0') || (*zip2 != '\0'))
+                                                       city = xstrappend(city, ",");
+                                       }
+                                                                               
+                                       /* concats all fields to one string and release */
+                                       wpt->description = nmn4_concat(zip1, city, street, number, zip2, NULL);
+                                       break;
+                       
+                               case 11:                                /* longitude */
+                                       sscanf(c, "%lf", &wpt->longitude);
+                                       break;
+                       
+                               case 12:                                /* latitude */
+                                       sscanf(c, "%lf", &wpt->latitude);
+                                       break;
+                       
+                       }
+                       c = csv_lineparse(NULL, "|", "", column++);
+               }
+               route_add_wpt(route, wpt);
+       }
+}
+
+static void 
+nmn4_route_hdr(const route_head *route)
+{
+       curr_rte_num++;
+}
+
+static void 
+nmn4_route_tlr(const route_head *rte)
+{
+}
+
+static void
+nmn4_write_waypt(const waypoint *wpt)
+{
+       char buff[1024], city[128], street[128], zipc[32], number[32];
+       int zip = -1;
+       
+       if (curr_rte_num != target_rte_num) return;
+
+       strncpy(city, "-", sizeof(city));
+       strncpy(street, "-", sizeof(street));
+       strncpy(zipc, "-", sizeof(zipc));
+       strncpy(number, "-", sizeof(number));
+       
+       /* 
+          Population of specific data used by Navigon may come in the
+          future or it may be impossible. We currently output only the 
+          coordinates in the output, but this is sufficient for Navigon.
+          
+          The coordinates are the only item we are about guaranteed to have 
+          when converting to any from any format, so we leave the other
+          fields unpopulated.  So i have to pay Navigon a compliment for 
+          implementing a simple data exchange.
+        */
+
+       fprintf(fout, "-|-|-|-|%s|%s|%s|%s|%s|-|-|%.5f|%.5f|-|-|\r\n",
+               zipc, city, zipc, street, number,
+               wpt->longitude, wpt->latitude);
+}
+
+static void
+nmn4_write_data(void)
+{
+       
+       target_rte_num = 1;
+       
+       if (index_opt != NULL)
+       {
+               target_rte_num = atoi(index_opt);
+               is_fatal(((target_rte_num > route_count()) || (target_rte_num < 1)),
+                       MYNAME ": invalid route number %d (1..%d))!\n", target_rte_num, route_count());
+       }
+       
+       curr_rte_num = 0;
+       route_disp_all(nmn4_route_hdr, nmn4_route_tlr, nmn4_write_waypt);
+}
+
+
+/* %%% global callbacks %%% */
+
+static void
+nmn4_rd_init(const char *fname)
+{
+       fin = xfopen(fname, "r", MYNAME);
+       fin_name = xstrdup(fname);
+}
+
+static void
+nmn4_rd_deinit(void)
+{
+       xfree(fin_name);
+       fclose(fin);
+}
+
+static void
+nmn4_read(void)
+{
+       nmn4_read_data();
+}
+
+static void
+nmn4_wr_init(const char *fname)
+{
+       fout = xfopen(fname, "w", MYNAME);
+       fout_name = xstrdup(fname);
+}
+
+static void
+nmn4_wr_deinit(void)
+{
+       xfree(fout_name);
+       fclose(fout);
+}
+
+static void
+nmn4_write(void)
+{
+       nmn4_write_data();
+}
+
+/* --------------------------------------------------------------------------- */
+
+ff_vecs_t nmn4_vecs = {
+       ff_type_file,
+       { ff_cap_none, ff_cap_read || ff_cap_write, ff_cap_none },
+       nmn4_rd_init,
+       nmn4_wr_init,
+       nmn4_rd_deinit,
+       nmn4_wr_deinit,
+       nmn4_read,
+       nmn4_write,
+       NULL,
+       nmn4_args,
+       CET_CHARSET_MS_ANSI, 1  /* CET-REVIEW */
+};
diff --git a/gpsbabel/reference/route/nmn4-sample-out.rte b/gpsbabel/reference/route/nmn4-sample-out.rte
new file mode 100644 (file)
index 0000000..4f00f9e
--- /dev/null
@@ -0,0 +1,10 @@
+-|-|-|-|-|-|-|-|-|-|-|12.10727|50.49425|-|-|\r
+-|-|-|-|-|-|-|-|-|-|-|12.01210|50.37575|-|-|\r
+-|-|-|-|-|-|-|-|-|-|-|12.07199|50.22467|-|-|\r
+-|-|-|-|-|-|-|-|-|-|-|12.67563|49.22528|-|-|\r
+-|-|-|-|-|-|-|-|-|-|-|12.55165|49.12409|-|-|\r
+-|-|-|-|-|-|-|-|-|-|-|12.26244|49.05546|-|-|\r
+-|-|-|-|-|-|-|-|-|-|-|12.22659|49.03302|-|-|\r
+-|-|-|-|-|-|-|-|-|-|-|11.76592|49.04841|-|-|\r
+-|-|-|-|-|-|-|-|-|-|-|11.61610|49.02190|-|-|\r
+-|-|-|-|-|-|-|-|-|-|-|11.58767|49.03485|-|-|\r
diff --git a/gpsbabel/reference/route/nmn4-sample.gpx b/gpsbabel/reference/route/nmn4-sample.gpx
new file mode 100644 (file)
index 0000000..58ae117
--- /dev/null
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<gpx
+ version="1.0"
+creator="GPSBabel - http://www.gpsbabel.org"
+xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xmlns="http://www.topografix.com/GPX/1/0"
+xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/GPX/1/0/gpx.xsd">
+<time>1970-01-01T00:00:00Z</time>
+<rte>
+  <rtept lat="50.494250000" lon="12.107270000">
+    <name>RPT001</name>
+    <cmt>08523 Plauen, Jahnstrasse 28</cmt>
+    <desc>08523 Plauen, Jahnstrasse 28</desc>
+  </rtept>
+  <rtept lat="50.375750000" lon="12.012100000">
+    <name>RPT002</name>
+    <cmt>08538 Burgstein, K7855</cmt>
+    <desc>08538 Burgstein, K7855</desc>
+  </rtept>
+  <rtept lat="50.224670000" lon="12.071990000">
+    <name>RPT003</name>
+    <cmt>95111 Rehau</cmt>
+    <desc>95111 Rehau</desc>
+  </rtept>
+  <rtept lat="49.225280000" lon="12.675630000">
+    <name>RPT004</name>
+    <cmt>93413 Cham, Further Strasse</cmt>
+    <desc>93413 Cham, Further Strasse</desc>
+  </rtept>
+  <rtept lat="49.124090000" lon="12.551650000">
+    <name>RPT005</name>
+    <cmt>93185 Michelsneukirchen, Hauptstrasse</cmt>
+    <desc>93185 Michelsneukirchen, Hauptstrasse</desc>
+  </rtept>
+  <rtept lat="49.055460000" lon="12.262440000">
+    <name>RPT006</name>
+    <cmt>93177 Altenthann</cmt>
+    <desc>93177 Altenthann</desc>
+  </rtept>
+  <rtept lat="49.033020000" lon="12.226590000">
+    <name>RPT007</name>
+    <cmt>93093 Donaustauf</cmt>
+    <desc>93093 Donaustauf</desc>
+  </rtept>
+  <rtept lat="49.048410000" lon="11.765920000">
+    <name>RPT008</name>
+    <cmt>93155 Hemau, Dietfurter Strasse</cmt>
+    <desc>93155 Hemau, Dietfurter Strasse</desc>
+  </rtept>
+  <rtept lat="49.021900000" lon="11.616100000">
+    <name>RPT009</name>
+    <cmt>92345 Mühlbach, Riedenburger Strasse</cmt>
+    <desc>92345 Mühlbach, Riedenburger Strasse</desc>
+  </rtept>
+  <rtept lat="49.034850000" lon="11.587670000">
+    <name>RPT010</name>
+    <cmt>92345 Dietfurt An Der Altmühl</cmt>
+    <desc>92345 Dietfurt An Der Altmühl</desc>
+  </rtept>
+</rte>
+</gpx>
diff --git a/gpsbabel/reference/route/nmn4-sample.rte b/gpsbabel/reference/route/nmn4-sample.rte
new file mode 100644 (file)
index 0000000..2a27a23
--- /dev/null
@@ -0,0 +1,10 @@
+-|-|17|-|08523|Plauen|08523|Jahnstrasse|28|-|-|12.10727|50.49425|-|-|\r
+-|-|17|-|08538|Burgstein|08538|K7855|-|-|-|12.01210|50.37575|-|-|\r
+-|-|17|-|95111|Rehau|-|-|-|-|-|12.07199|50.22467|-|-|\r
+-|-|17|-|93413|Cham|93413|Further Strasse|-|-|-|12.67563|49.22528|-|-|\r
+-|-|17|-|93185|Michelsneukirchen|93185|Hauptstrasse|-|-|-|12.55165|49.12409|-|-|\r
+-|-|17|-|93177|Altenthann|-|-|-|-|-|12.26244|49.05546|-|-|\r
+-|-|17|-|93093|Donaustauf|-|-|-|-|-|12.22659|49.03302|-|-|\r
+-|-|17|-|93155|Hemau|93155|Dietfurter Strasse|-|-|-|11.76592|49.04841|-|-|\r
+-|-|17|-|92345|Mühlbach|92345|Riedenburger Strasse|-|-|-|11.61610|49.02190|-|-|\r
+-|-|17|-|92345|Dietfurt An Der Altmühl|-|-|-|-|-|11.58767|49.03485|-|-|\r
index 6b2223fbfe602da68d0844870e34a9fa63215c39..f4d0a631d64a34051809ae7df916cfafcb29f362 100755 (executable)
@@ -866,11 +866,20 @@ rm -f ${TMPDIR}/cst-*
 ${PNAME} -i cst -f reference/route/cst-sample.cst -o gpx -F ${TMPDIR}/cst-sample.gpx
 compare ${TMPDIR}/cst-sample.gpx reference/route/cst-sample.gpx
 
+#
+# Navigon Mobile Navigator .rte tests
+#
+rm -f ${TMPDIR}/nmn4-sample*
+${PNAME} -i nmn4 -f reference/route/nmn4-sample.rte -o gpx -F ${TMPDIR}/nmn4-sample.gpx
+compare reference/route/nmn4-sample.gpx ${TMPDIR}/nmn4-sample.gpx
+${PNAME} -i gpx -f reference/route/nmn4-sample.gpx -o nmn4 -F ${TMPDIR}/nmn4-sample-out.rte
+compare reference/route/nmn4-sample-out.rte ${TMPDIR}/nmn4-sample-out.rte
+
 #
 # Navigon Mobile Navigator 5 .pdb (read-only)
 #
 rm -f ${TMPDIR}/nmn5-sample*
 # ${PNAME} -i nmn5 -f reference/route/nmn5-sample.pdb -o gpx -F ${TMPDIR}/nmn5-sample.gpx
-# compare ${TMPDIR}/nmn5-sample.gpx reference/route/nmn5-sample.gpx
+# compare reference/route/nmn5-sample.gpx ${TMPDIR}/nmn5-sample.gpx
 
 exit 0
index 72f8ad0662729b12c0da529db4f6591f3159a990..dcb9c052c6bd28d4e6dbc625f15020a7de88db2e 100644 (file)
@@ -90,6 +90,7 @@ extern ff_vecs_t ignr_vecs;
 extern ff_vecs_t stmwpp_vecs;
 extern ff_vecs_t msroute_vecs;
 extern ff_vecs_t cst_vecs;
+extern ff_vecs_t nmn4_vecs;
 extern ff_vecs_t nmn5_vecs;
 
 static
@@ -457,6 +458,12 @@ vecs_t vec_list[] = {
                "CarteSurTable data file",
                "cst"
        },
+       {
+               &nmn4_vecs,
+               "nmn4",
+               "Navigon Mobile Navigator .rte files",
+               "rte"
+       },
        {
                &nmn5_vecs,
                "nmn5",